package com.gitee.zhziyun.cnfsystem.ui;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitee.zhziyun.cnfsystem.config.AvatarConfig;
import com.gitee.zhziyun.cnfsystem.config.IpPortConfig;
import com.gitee.zhziyun.cnfsystem.master.AppMaster;
import com.gitee.zhziyun.cnfsystem.model.FileAccept;
import com.gitee.zhziyun.cnfsystem.model.FileSource;
import com.gitee.zhziyun.cnfsystem.model.UserInfo;
import com.gitee.zhziyun.cnfsystem.utils.FileUtil.ThreadedFileReceiver;
import com.gitee.zhziyun.cnfsystem.utils.FileUtil.ThreadedFileSender;
import com.gitee.zhziyun.cnfsystem.utils.IpAddressUtil;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class ChatUI extends JFrame {
    private final String chatTarget;      // 当前聊天对象（用户名或群组号）
    private final AppMaster appMaster;    // 应用主控接口

    private final Map<String, UserInfo> ipUserMap;

    public Map<String, ThreadedFileSender> getFileSenderMap() {
        return fileSenderMap;
    }

    private final Map<String, ThreadedFileSender> fileSenderMap = new HashMap<>();
    
    private final JScrollPane centerPane;
    private final JPanel messagePanel;

    private final boolean isMulticast;

    String sendIp;
    int sendPort;

    public interface CloseWindow {
        void onCloseWindow();
    }

    // 构造函数
    public ChatUI(AppMaster appMaster, String sendIp, int sendPort, CloseWindow closeWindow) {//
        this.appMaster = appMaster;
        this.ipUserMap = appMaster.getIpUserMap();
        this.sendIp = sendIp;
        this.sendPort = sendPort;

        if (sendIp.equals(IpPortConfig.getMulticastIp())) {
            this.isMulticast = true;
            this.chatTarget = "群聊";
        } else {
            this.isMulticast = false;
            this.chatTarget = ipUserMap.get(sendIp).getUserName();
        }

        messagePanel = createMessagePanel();
        this.centerPane = createCenterPanel();

        // 设置窗口基本属性
        setTitle("聊天窗口" + " - " + chatTarget);       // 窗口标题显示聊天对象
        setSize(800, 600);                 // 设置窗口大小
        setResizable(false);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // 关闭时只销毁当前窗口
        addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent windowEvent) {
                try {
                    closeWindow.onCloseWindow();
                } catch (Exception e) {
                    System.err.printf("关闭 %s 发生错误：%s\n", "聊天窗口" + " - " + chatTarget, e);
                }
            }
        });

        setLocationRelativeTo(null);       // 窗口居中显示

        // 使用边界布局管理窗口组件
        setLayout(new BorderLayout());

        // 创建并添加顶部标题区域
        add(createTopPanel(), BorderLayout.NORTH);

        // 创建并添加中部聊天记录区域
        add(centerPane, BorderLayout.CENTER);

        // 创建并添加底部输入区域
        add(createBottomPanel(), BorderLayout.EAST);

        // 显示窗口
        setVisible(true);
    }

    // 创建顶部标题面板
    private JPanel createTopPanel() {
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); // 居中布局

        // 创建标题标签
        JLabel titleLabel = new JLabel(chatTarget);
        titleLabel.setFont(new Font("宋体", Font.BOLD, 16)); // 设置字体加粗
        topPanel.add(titleLabel);

        return topPanel;
    }

    // 创建中部聊天记录面板
    private JScrollPane createCenterPanel() {
        // 创建滚动面板用于显示聊天记录
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        // 将聊天记录容器添加到滚动面板
        scrollPane.setViewportView(messagePanel);

        return scrollPane;
    }

    private JPanel createMessagePanel() {
        // 创建聊天记录容器（使用垂直盒子布局）
        JPanel messagePanel = new JPanel();
        messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS));
        return messagePanel;
    }

    // 创建底部输入面板
    private JPanel createBottomPanel() {
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BorderLayout());
        bottomPanel.setBorder(new EmptyBorder(0, 10, 10, 10)); // 添加内边距

        // 创建文本输入区
        JTextArea textArea = new JTextArea(3, 20);
        textArea.setLineWrap(true); // 自动换行
        JScrollPane textScroll = new JScrollPane(textArea);
        bottomPanel.add(textScroll, BorderLayout.CENTER);

        // 创建按钮面板
        JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 10, 0));
        buttonPanel.setBorder(new EmptyBorder(10, 0, 0, 0));

        // 创建"发送文本"按钮
        JButton textButton = new JButton("发送文本");
        textButton.addActionListener(e -> {
            String text = textArea.getText().trim();
            if (!text.isEmpty()) {
                // 调用监听器处理文本发送
                try {
                    if (isMulticast) {
                        appMaster.multicastMessage(text);
                    } else {
                        addTextMessage(
                                IpPortConfig.getLocalIp(),
                                text,
                                true  // 添加参数：标识本机发送的消息
                        );
                        appMaster.sendMessageToUser(text, sendIp, sendPort);
                    }

                } catch (JsonProcessingException ex) {
                    throw new RuntimeException(ex);
                }

                textArea.setText(""); // 清空输入框
            }
        });

        // 创建"发送文件"按钮
        JButton fileButton = new JButton("发送文件");

        fileButton.addActionListener(e -> {

            JFileChooser fileChooser = new JFileChooser();
            int result = fileChooser.showOpenDialog(ChatUI.this);

            if (result == JFileChooser.APPROVE_OPTION) {

                File selectedFile = fileChooser.getSelectedFile();
                FileSource fileSource = new FileSource(selectedFile.getName());

                addFileSendMessage(fileSource, selectedFile.getAbsolutePath());

                try {
                    if (isMulticast) {
                        appMaster.multicastFile(fileSource, sendIp, sendPort);
                    } else {
                        appMaster.sendFileToUser(fileSource, sendIp, sendPort);
                    }
                } catch (JsonProcessingException ex) {
                    throw new RuntimeException(ex);
                }
            }
        });

        // 将按钮添加到按钮面板
        buttonPanel.add(textButton);
        buttonPanel.add(fileButton);

        // 将按钮面板添加到底部面板的南部
        bottomPanel.add(buttonPanel, BorderLayout.SOUTH);

        return bottomPanel;
    }

    public JPanel createMessageEntry(String ip, boolean isSentByMe, JPanel contentPanel) {
        UserInfo userInfo = ipUserMap.get(ip);
        JPanel messageEntry = new JPanel(new BorderLayout());
        messageEntry.setBorder(new EmptyBorder(5, 5, 5, 5)); // 添加内边距

        // 创建头像面板（垂直布局：用户名在头像正上方）
        JPanel avatarPanel = new JPanel();
        avatarPanel.setLayout(new BoxLayout(avatarPanel, BoxLayout.Y_AXIS));
        avatarPanel.setAlignmentY(Component.TOP_ALIGNMENT); // 顶部对齐

        // 创建用户名标签并居中显示
        JLabel nameLabel = new JLabel(userInfo.getUserName());
        nameLabel.setFont(nameLabel.getFont().deriveFont(Font.BOLD)); // 用户名加粗
        nameLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));

        // 创建头像标签
        JLabel avatarLabel = new JLabel();
        setFixedSizeAvatar(userInfo.getAvatarId(), avatarLabel);            // 设置固定大小头像
        avatarLabel.setAlignmentX(Component.CENTER_ALIGNMENT);              // 头像居中

        // 头像添加到头像面板
        avatarPanel.add(avatarLabel);
        avatarPanel.add(Box.createVerticalStrut(5));     // 用户名与头像间距5px

        // 将用户名标签添加到内容面板
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPanel.add(nameLabel, BorderLayout.NORTH);

        // 修改：根据消息方向调整布局
        if (isSentByMe) {
            // 发送的消息：头像在右侧
            nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); // 停靠位置关键设置
            messageEntry.add(avatarPanel, BorderLayout.EAST);       // 头像在右侧
            messageEntry.add(contentPanel, BorderLayout.CENTER);       // 文本在左侧
        } else {
            // 接收的消息：头像在左侧
            nameLabel.setHorizontalAlignment(SwingConstants.LEFT);  // 停靠位置关键设置
            messageEntry.add(avatarPanel, BorderLayout.WEST);       // 头像在左侧
            messageEntry.add(contentPanel, BorderLayout.CENTER);       // 文本在右侧
        }

        // 设置消息面板高度约束
        messageEntry.setMinimumSize(new Dimension(0, 80));                      // 最小高度80px
        messageEntry.setMaximumSize(new Dimension(Integer.MAX_VALUE, Short.MAX_VALUE));      // 允许高度自适应

        return messageEntry;
    }

    // 添加文本消息到聊天记录
    public void addTextMessage(String ip, String message, boolean isSentByMe) {
        // 创建单条消息面板
        JPanel contentPanel = new JPanel(new BorderLayout());
        JPanel messageEntry = createMessageEntry(ip, isSentByMe, contentPanel);

        // 创建文本区域
        JTextArea textArea = new JTextArea(message);
        textArea.setLineWrap(true);       // 启用自动换行
        textArea.setWrapStyleWord(true);  // 按单词边界换行
        textArea.setEditable(false);      // 设置为不可编辑
        textArea.setOpaque(false);        // 透明背景
        textArea.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); // 添加内边距提升可读性
        textArea.setFont(new JLabel().getFont()); // 使用与JLabel相同的字体
        contentPanel.add(textArea, BorderLayout.CENTER);

        // 设置发送消息的背景为白色
        textArea.setOpaque(true);
        textArea.setBackground(Color.WHITE);
        textArea.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); // 添加浅灰色边框增强视觉效果

        // 添加到聊天记录容器
        messagePanel.add(messageEntry); // 添加到顶部，确保新消息在最下方

        // 滚动到底部
        SwingUtilities.invokeLater(() -> {
            JScrollBar scrollBar = centerPane.getVerticalScrollBar();
            scrollBar.setValue(scrollBar.getMaximum());
        });

        // 刷新界面显示
        revalidate();
        repaint();
    }

    // 添加文件接收消息到聊天记录
    public void addFileSendMessage(FileSource fileSource, String filePath) {
        // 创建单条消息面板
        JPanel contentPanel = new JPanel(new BorderLayout());
        JPanel messageEntry = createMessageEntry(IpPortConfig.getLocalIp(), true, contentPanel);

        // 创建文件信息面板
        JPanel fileInfoPanel = new JPanel(new BorderLayout());
        fileInfoPanel.add(new JLabel(fileSource.getFileName()), BorderLayout.NORTH);

        // 创建按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
//        JButton cancelButton = new JButton("取消发送");

//        buttonPanel.add(cancelButton);
        buttonPanel.add(new JLabel("发送中"));
        buttonPanel.setBackground(Color.WHITE);
        fileInfoPanel.add(buttonPanel, BorderLayout.CENTER);

        // 创建进度条
        JProgressBar progressBar = new JProgressBar(0, 100);
        fileInfoPanel.add(progressBar, BorderLayout.SOUTH);

        // 创建发送器
        ThreadedFileSender fileSender = new ThreadedFileSender(filePath, new ThreadedFileSender.ProgressListener() {
            @Override
            public void onProgress(long current, long total) {
                progressBar.setValue((int) (current * 100 / total));
                revalidate();
                repaint();
            }

            @Override
            public void onPaused() {
                progressBar.setString("暂停中");
                revalidate();
                repaint();
            }

            @Override
            public void onCompleted() {
                fileSenderMap.remove(fileSource.getUUID());
                progressBar.setString("完成");
                buttonPanel.removeAll();
                buttonPanel.add(new JLabel("发送成功"));
                revalidate();
                repaint();
            }
        });

        // 添加按钮监听器

//        cancelButton.addActionListener(e -> {
//            fileSender.cancel();
//            buttonPanel.removeAll();
//            fileInfoPanel.remove(progressBar);
//            buttonPanel.add(new Label("发送已取消"));
//            revalidate();
//            repaint();
//        });
        fileSenderMap.put(fileSource.getUUID(), fileSender);

        // 将文件信息容器添加到主面板的CENTER区域
        contentPanel.add(fileInfoPanel, BorderLayout.CENTER);


        // 设置发送消息的背景为白色
        fileInfoPanel.setOpaque(true);
        fileInfoPanel.setBackground(Color.WHITE);
        fileInfoPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));


        // 添加到聊天记录容器
        messagePanel.add(messageEntry);

        // 滚动到底部
        SwingUtilities.invokeLater(() -> {
            JScrollBar scrollBar = centerPane.getVerticalScrollBar();
            scrollBar.setValue(scrollBar.getMaximum());
        });

        // 刷新界面显示
        revalidate();
        repaint();
    }

    // 添加文件接收消息到聊天记录
    public void addFileReceiveMessage(String ip, FileSource fileSource, boolean isSentByMe) {
        // 创建单条消息面板
        JPanel contentPanel = new JPanel(new BorderLayout());
        JPanel messageEntry = createMessageEntry(ip, isSentByMe, contentPanel);

        // 创建文件信息面板
        JPanel fileInfoPanel = new JPanel(new BorderLayout());
        fileInfoPanel.add(new JLabel(fileSource.getFileName()), BorderLayout.NORTH);

        // 创建按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JButton acceptButton = new JButton("接收");
        JButton cancelButton = new JButton("取消");
        JButton stopButton = new JButton("暂停");
        JButton resumeButton = new JButton("继续");

        buttonPanel.add(acceptButton);
        buttonPanel.add(cancelButton);
        buttonPanel.setBackground(Color.WHITE);
        fileInfoPanel.add(buttonPanel, BorderLayout.CENTER);

        // 创建进度条
        JProgressBar progressBar = new JProgressBar(0, 100);

        // 创建接受器
        int port = IpAddressUtil.getAvailablePort();
        ThreadedFileReceiver receiver = new ThreadedFileReceiver(port, "./ReceiveFiles", new ThreadedFileReceiver.ProgressListener() {
            @Override
            public void onProgress(long current, long total) {
                progressBar.setValue((int) (current * 100 / total));
                revalidate();
                repaint();
            }

            @Override
            public void onPaused() {
                progressBar.setString("暂停中");
                revalidate();
                repaint();
            }

            @Override
            public void onCompleted() {
                progressBar.setString("完成");
                buttonPanel.removeAll();
                buttonPanel.add(new JLabel("已接收"));
                revalidate();
                repaint();
            }
        });

        // 添加按钮监听器
        acceptButton.addActionListener(e -> {
            receiver.start();
            try {
                FileAccept fileAccept = new FileAccept(port, fileSource.getUUID());
                if (isMulticast) {
                    appMaster.multicastAcceptFile(fileAccept, sendIp, sendPort);
                } else {
                    appMaster.acceptFile(fileAccept, sendIp, sendPort);
                }
            } catch (JsonProcessingException ex) {
                throw new RuntimeException(ex);
            }
            buttonPanel.removeAll();
            buttonPanel.add(stopButton);
            buttonPanel.add(cancelButton);

            fileInfoPanel.add(progressBar, BorderLayout.SOUTH);
            revalidate();
            repaint();
        });

        cancelButton.addActionListener(e -> {
            receiver.cancel();
            buttonPanel.removeAll();
            fileInfoPanel.remove(progressBar);
            buttonPanel.add(new Label("已拒绝"));
            revalidate();
            repaint();
        });

        stopButton.addActionListener(e -> {
            receiver.pause();
            buttonPanel.removeAll();
            buttonPanel.add(resumeButton);
            buttonPanel.add(cancelButton);
            revalidate();
            repaint();
        });

        resumeButton.addActionListener(e -> {
            receiver.resume();
            buttonPanel.removeAll();
            buttonPanel.add(stopButton);
            buttonPanel.add(cancelButton);
            revalidate();
            repaint();
        });

        // 将文件信息容器添加到主面板的CENTER区域
        contentPanel.add(fileInfoPanel, BorderLayout.CENTER);


        // 设置发送消息的背景为白色
        fileInfoPanel.setOpaque(true);
        fileInfoPanel.setBackground(Color.WHITE);
        fileInfoPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));


        // 添加到聊天记录容器
        messagePanel.add(messageEntry);

        // 滚动到底部
        SwingUtilities.invokeLater(() -> {
            JScrollBar scrollBar = centerPane.getVerticalScrollBar();
            scrollBar.setValue(scrollBar.getMaximum());
        });

        // 刷新界面显示
        revalidate();
        repaint();
    }

    // 封装头像设置方法（固定尺寸）
    private void setFixedSizeAvatar(int avatarId, JLabel icon) {
        try {
            // 获取原始头像图标
            ImageIcon originalIcon = new ImageIcon(
                    Objects.requireNonNull(getClass().getResource(AvatarConfig.getPathById(avatarId)))
            );

            // 缩放图片到固定尺寸
            Image scaledImg = originalIcon.getImage().getScaledInstance(40, 40, Image.SCALE_SMOOTH);
            icon.setIcon(new ImageIcon(scaledImg));
            icon.setPreferredSize(new Dimension(40, 40)); // 设置固定尺寸
        } catch (Exception e) {
            // 头像加载失败时清除图标
            icon.setIcon(null);
            System.err.println("头像加载失败: " + e.getMessage());
        }
    }
}